package com.spring.demo.rabbit.config;

import com.spring.demo.rabbit.ExchangeConst;
import com.spring.demo.rabbit.QueueConst;
import com.spring.demo.rabbit.RoutingKeyConst;
import lombok.Data;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/***
 * @title BusinessExchangeCOnfig
 * @description: TTL和死信队列实现延迟消息
 *          但是队列消息采用先进先出。
 *          如果第一条消息的延迟时间是20秒，第二条消息的延迟时间是10秒。两条消息同一时间入队（投递），则两条同一时间出队（被消息）
 * @author baiji
 * @version 1.0.0
 * @create 2023/9/7 10:52
 **/
@Configuration
@Data
public class BusinessExchangeConfig {

    /**
     * 声明业务队列的交换器
     *
     * @return
     */
    @Bean("businessExchange")
    public DirectExchange businessExchange() {
        return new DirectExchange(ExchangeConst.BUSINESS_EXCHANGE);
    }

    /**
     * 声明死信队列的交换器
     *
     * @return
     */
    @Bean("deadLetterExchange")
    public DirectExchange deadLetterExchange() {
        return new DirectExchange(ExchangeConst.DEAD_LETTER_EXCHANGE);
    }

    /**
     * 声明业务队列
     *
     * @return
     */
    @Bean("businessQueue")
    public Queue businessQueue() {
        return QueueBuilder.durable(QueueConst.BUSINESS_QUEUE)
                // 设置当前队列绑定的死信队列交换器
                .deadLetterExchange(ExchangeConst.DEAD_LETTER_EXCHANGE)
                // 设置当前队列绑定的死信队列路由键
                .deadLetterRoutingKey(RoutingKeyConst.DEAD_LETTER_ROUTING_KEY)
                // 设置消息的过期时间 单位： ms (毫秒)
                .ttl(5000)
                .build();
    }

    /**
     * 声明私信队列
     *
     * @return
     */
    @Bean("deadLetterQueue")
    public Queue deadLetterQueue() {
        return QueueBuilder.durable(QueueConst.DEAD_LETTER_QUEUE).build();
    }

    /**
     * 声明业务队列和业务交换器的绑定关系
     *
     * @param exchange
     * @param queue
     * @return
     */
    @Bean("businessBinding")
    public Binding businessBinding(@Qualifier("businessExchange") DirectExchange exchange,
                                   @Qualifier("businessQueue") Queue queue) {
        return BindingBuilder.bind(queue).to(exchange).with(RoutingKeyConst.BUSINESS_ROUTING_KEY);
    }

    /**
     * 声明私信队列和业务交换器的绑定关系
     *
     * @param exchange
     * @param queue
     * @return
     */
    @Bean("deadLetterBinding")
    public Binding deadLetterBinding(@Qualifier("deadLetterExchange") DirectExchange exchange,
                                     @Qualifier("deadLetterQueue") Queue queue) {
        return BindingBuilder.bind(queue).to(exchange).with(RoutingKeyConst.DEAD_LETTER_ROUTING_KEY);
    }
}
